﻿using System;
using System.IO;

namespace BitPongTetrisAlgorithm
{
    class BitPongTetris
    {
        public static void MainAlgorithm(string inputData, Action<long, int> printField)
        {
            using (StringReader reader = new StringReader(inputData))
            {
                const int Rows = 16;
                const int Columns = 4;
                const int Bits = Rows * Columns;

                //Reading input
                long field = 0;
                long fallingObject = 0;

                for (int col = 0; col < Columns; col++)
                {
                    short column = short.Parse(reader.ReadLine());

                    for (int row = 0; row < Rows / 2; row++)
                    {
                        if (((column >> row) & 1) == 1)
                        {
                            fallingObject |= (1L << (4 * row + col));
                        }
                    }

                    for (int row = Rows / 2; row < Rows; row++)
                    {
                        if (((column >> row) & 1) == 1)
                        {
                            field |= (1L << (4 * row + col));
                        }
                    }
                }

                int dx = int.Parse(reader.ReadLine());
                int dy = 1;
                //End reading input!

                //Moving the object until it reaches the ground
                bool hasReachedTheGround = false;
                while (!hasReachedTheGround)
                {
                    printField(field | fallingObject, dx);
                    //Trying to move to next position
                    bool isColliding = false;
                    long newFalling = 0;

                    for (int bit = 0; bit < Bits; bit++)
                    {
                        if (((fallingObject >> bit) & 1) == 1)
                        {
                            int col = bit % Columns;
                            int row = (bit - col) / Columns;

                            row += dy;
                            col += dx;

                            newFalling |= (1L << (4 * row + col));

                            if (row < 0 || row >= Rows || col < 0 || col >= Columns || (newFalling & field) != 0)
                            {
                                isColliding = true;
                                break;
                            }
                        }
                    }

                    if (!isColliding)
                    {
                        fallingObject = newFalling;
                        continue;
                    }
                    else
                    {
                        dx *= -1;
                    }


                    //Trying to move in bounced position
                    isColliding = false;
                    newFalling = 0;

                    for (int bit = 0; bit < Bits; bit++)
                    {
                        if (((fallingObject >> bit) & 1) == 1)
                        {
                            int col = bit % Columns;
                            int row = (bit - col) / Columns;

                            row += dy;
                            col += dx;

                            newFalling |= (1L << (4 * row + col));

                            if (row < 0 || row >= Rows || col < 0 || col >= Columns || (newFalling & field) != 0)
                            {
                                isColliding = true;
                                break;
                            }
                        }
                    }

                    if (!isColliding)
                    {
                        fallingObject = newFalling;
                        continue;
                    }
                    else
                    {
                        dx = 0;
                    }


                    //Trying to move down
                    isColliding = false;
                    newFalling = 0;

                    for (int bit = 0; bit < Bits; bit++)
                    {
                        if (((fallingObject >> bit) & 1) == 1)
                        {
                            int col = bit % Columns;
                            int row = (bit - col) / Columns;

                            row += dy;
                            col += dx;

                            newFalling |= (1L << (4 * row + col));

                            if (row < 0 || row >= Rows || col < 0 || col >= Columns || (newFalling & field) != 0)
                            {
                                isColliding = true;
                                break;
                            }
                        }
                    }

                    if (!isColliding)
                    {
                        fallingObject = newFalling;
                        continue;
                    }
                    else
                    {
                        hasReachedTheGround = true;
                        field |= fallingObject;
                    }
                }


                //Collapsing rows after the fallingObject has fallen
                int rowsToFallDown = 0;
                int bitsOnRow = 0;

                for (int bit = Bits - 1; bit >= 0; bit--)
                {
                    if (((field >> bit) & 1) == 1)
                    {
                        bitsOnRow++;
                    }

                    if (bit % Columns == 0)
                    {
                        if (bitsOnRow == Columns)
                        {
                            rowsToFallDown++;

                            //Collapsing a row
                            for (int i = 0; i < Columns; i++)
                            {
                                field &= (~(1L << (bit + i)));
                            }
                        }
                        else
                        {
                            //Moving down a row if any rows to fall down                        
                            for (int i = 0; i < Columns; i++)
                            {
                                if (((field >> (bit + i)) & 1L) == 1)
                                {
                                    field &= (~(1L << (bit + i)));
                                    field |= (1L << (bit + i + 4 * rowsToFallDown));
                                }
                            }
                        }

                        bitsOnRow = 0;
                    }
                }

                //Printing result field
                printField(field, dx);
                //for (int bit = 0; bit < Bits; bit++)
                //{
                //    Console.Write("{0}", ((field >> bit) & 1) == 1 ? '*' : '.');

                //    if (bit % 4 == 3)
                //    {
                //        Console.WriteLine();
                //    }
                //}

            }
        }
    }
}
